﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
#include <assert.h>

using namespace std;

//double Test()
//{
//	return 2.2;
//}
//
//int main()
//{
//	std::vector<int> v = { 1,2,3,4,5 };
//
//	// 可以直接使用auto自动去推导类型，例如：
//	auto i = *v.begin();
//	std::cout << typeid(i).name() << std::endl; 
//
//
//	// 也可以去推导一个复杂的函数返回类型，
//	// 这里模拟演示，就设置Test函数的返回值为double：
//
//	auto result = Test();
//	std::cout << typeid(result).name() << std::endl; 
//
//	return 0;
//}


//int main()
//{
//
//	int a = 1;
//	decltype(a) b = a; // 此时b的类型为int
//	std::cout << typeid(b).name() << std::endl; 
//
//	// 可以使用decltype来引用函数的返回类型：Test函数类型为double
//	decltype(Test()) c = Test(); // 此时c的类型为double
//	std::cout << typeid(c).name() << std::endl;
//
//	// 可以使用decltype来处理复杂的表达式：
//	int* ptr = &a;
//	decltype(*ptr) d = *ptr; // 此时d的类型为int
//	std::cout << typeid(d).name() << std::endl;
//
//	// 如下：即使没有定义x，y也可以得到x+y的类型，但是x，y必须得先声明
//	int x, y;
//	decltype(x + y) z; // 此时z的类型为int
//	std::cout << typeid(z).name() << std::endl;
//
//	return 0;
//}

//class A
//{
//public:
//	virtual void func()
//	{ cout << "111" << endl; }
//};
//
//class B : public A
//{
//public:
//	virtual void func2() override
//	{ cout << 222 << endl; }
//};
//
//
//
//int main()
//{
//
//	return 0;
//}


//class A
//{
//public:
//	// 让编译器再生成一个无参的构造函数
//	A() = default;
//
//	A(int a) :_a(a) 
//	{}
//
//	// 让编译器不生成默认的拷贝构造和赋值重载函数
//	A(const A&) = delete;
//	A& operator=(const A&) = delete;
//
//private:
//	int _a = 1;
//};
//
//int main()
//{
//	A a;
//	A b(a);
//
//	return 0;
//}
//char* my_strncpy(char* dest, const char* src, size_t num)
//{
//	char* ret = dest;
//	int i = 0;
//	assert(dest && src);	//用assert断言保证其不为野指针
//
//	//1.用while循环实现将拷贝num个字符从源字符串到目标空间。
//
//	//设置跳出循环条件->当源字符串走到'/0'或拷贝到第num个字符
//	while (*src && i < num)
//	{
//		*ret++ = *src++;
//		i++;
//	}
//
//	//2.满足第2个条件->	
//	//如果源字符串的长度小于num，则拷贝完源字符串之后，在目标的后边追加0，直到num个。
//	for (int j = i; j < num; j++)
//	{
//		*ret++ = 0;
//	}
//
//	return ret;
//}
//
////功能演示:
//int main()
//{
//	char arr1[20] = "Hello World";
//	char arr2[] = "World Hello";
//	char* a = my_strncpy(arr2, arr1, 5);
//	printf("%s\n", arr2);
//	printf("%s\n", a);
//	return 0;
//}

//int main()
//{
//	int a = 1, b = 2;
//
//	auto add = [](int x, int y) { 
//		return x + y;
//	};
//	
//	cout << add(a, b) << endl; // 使用方法类似函数
//
//	return 0;
//}

int main()
{
    int a = 1, b = 2;
    // 捕捉列表

    auto swap1 = [a, b]() mutable // 还是传值捕捉
    {
        int tmp = a;
        a = b;
        b = tmp;
    };
    swap1();
    // 如果不加mutable的话a, b捕捉到的默认是const的，无法对其做出修改操作，而且·此ab非局部的那俩ab
    // 也就是mutable没啥用，修改内部的并不会改变外部
    printf("%d %d\n", a, b);


    // 引用捕捉
    auto swap2 = [&a, &b]() {
        int tmp = a;
        a = b;
        b = tmp;
    };
    swap2();
    printf("%d %d", a, b);

    // 捕捉方式还有 =, &
    // = 为传值捕捉所有父作用域中的变量，包括this
    // & 为引用捕捉所有父作用域中的变量，包括this

    // 还可以混合捕捉: 表示为&捕捉全局，唯独b为传值捕捉（也可以反着来）
    auto func = [&, b]() {};

    return 0;
}